/*******************************************************************************
 * Copyright (c) 2007, Geophysical Center RAS
 * Sergey Berezin, Dmitry Voitsekhovskiy
 * All rights reserved.
 *
 * Redistribution and use in source and binary forms,
 * with or without modification, are permitted provided
 * that the following conditions are met:
 *
 * - Redistributions of source code must retain the above copyright notice,
 * this list of conditions and the following disclaimer.
 *
 * - Redistributions in binary form must reproduce the above copyright notice,
 * this list of conditions and the following disclaimer in the documentation
 * and/or other materials provided with the distribution.
 *
 * - Neither the name of the Geophysical Center RAS nor the names
 * of its contributors may be used to endorse or promote products
 * derived from this software without specific prior written permission.
 *
 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND
 * CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES,
 * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
 * FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL
 * THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
 * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
 * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
 * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
 * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 ******************************************************************************/
using System;
using System.Diagnostics;

namespace VisualEsse.DataEngine.Types
{
	public class ScalarArray2d : IDirectAccessScalarArray2d
	{
		private double[,] data;

		public ScalarArray2d(int width, int height)
		{
			data = new double[width, height];
		}

		public ScalarArray2d(double [,] data)
		{
			this.data = data;
		}

		public ScalarArray2d(IScalarArray2d array2d)
		{
			this.data = new double[array2d.Width, array2d.Height];

			for(int i = 0; i < array2d.Width; i++)
				for(int j = 0; j < array2d.Height; j++)
                    data[i,j] = array2d[i,j];
		}

		public ScalarArray2d(IDirectAccessScalarArray2d array2d)
		{
			this.data = array2d.Data;
		}

        public static void GetMaxMin(IScalarArray2d data, out double max, out double min)
        {
            min = double.MaxValue;
            max = double.MinValue;
            for (int i = 0; i < data.Width; i++)
            {
                for (int j = 0; j < data.Height; j++)
                {
                    if (data[i, j] < min)
                        min = data[i, j];
                    if (data[i, j] > max)
                        max = data[i, j];
                }
            }
        }

        public static double Interpolate(IScalarArray2d data, double alpha, double beta, int i, int j)
        {
            Debug.Assert(i >= 0 && i < data.Width - 1 && j >= 0 && j < data.Height - 1);
            return data[i, j] * (1 - alpha) * (1 - beta) +
                   data[i + 1, j] * alpha * (1 - beta) +
                   data[i, j + 1] * (1 - alpha) * beta +
                   data[i + 1, j + 1] * alpha * beta;
        }

		#region IScalarArray2d Members

		public int Width
		{
			get
			{				
				return data.GetLength(0);
			}
		}

		public int Height
		{
			get
			{
				return data.GetLength(1);
			}
		}

		public double this[int i, int j]
		{
			get
			{				
				return data[i,j];
			}
			set
			{
				data[i,j] = value;
			}
		}

		public double[,] Data
		{
			get
			{
				return data;
			}
		}

		#endregion
	}

	public class ScalarArray3d : IDirectAccessScalarArray3d
	{
		private double[,,] data;

		public ScalarArray3d(int width, int height, int depth)
		{
			data = new double[width, height, depth];
		}

		public ScalarArray3d(double [,,] data)
		{
			this.data = data;
		}

		#region IScalarArray3d Members

		public int Width
		{
			get
			{				
				return data.GetLength(0);
			}
		}

		public int Height
		{
			get
			{
				return data.GetLength(1);
			}
		}

		public int Depth
		{
			get
			{
				return data.GetLength(2);
			}
		}

		public double this[int i, int j, int k]
		{
			get
			{				
				return data[i,j,k];
			}
			set
			{
				data[i,j,k] = value;
			}
		}

		public double[,,] Data
		{
			get
			{
				return data;
			}
		}

		#endregion
	}
}